package com.youbug.mall.product_pms.service.impl;

import com.youbug.common.to.SeckillSkuTo;
import com.youbug.common.to.SkuHasStockTo;
import com.youbug.common.vo.CommonSelectVo;
import com.youbug.common.vo.CommonTreeVo;
import com.youbug.common.vo.R;
import com.youbug.mall.product_pms.entity.*;
import com.youbug.mall.product_pms.feign.IPmsSeckillFeignService;
import com.youbug.mall.product_pms.feign.IWareFeignService;
import com.youbug.mall.product_pms.mapper.PmsSkuInfoMapper;
import com.youbug.mall.product_pms.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youbug.mall.product_pms.vo.SkuItemSaleAttrVo;
import com.youbug.mall.product_pms.vo.SkuItemVo;
import com.youbug.mall.product_pms.vo.SpuItemAttrGroupVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.youbug.mall.product_pms.entity.PmsSkuInfo;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import com.youbug.common.vo.QueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * <p>
 * sku信息 服务实现类
 * </p>
 *
 * @author youbug
 * @since 2024-04-21
 */
@Service
public class PmsSkuInfoServiceImpl extends ServiceImpl<PmsSkuInfoMapper, PmsSkuInfo> implements IPmsSkuInfoService {
        @Autowired
        private ICategoryService categoryService;

        @Autowired
        private IPmsBrandService brandService;

        @Autowired
        private IPmsSkuImagesService skuImagesService;

        @Autowired
        private IPmsSkuSaleAttrValueService skuSaleAttrValueService;

        @Autowired
        private IPmsSpuInfoDescService spuInfoDescService;

        @Autowired
        private IAttrGroupService attrGroupService;

        @Autowired
        private IPmsSeckillFeignService seckillFeignService;

        @Autowired
        private IWareFeignService wareFeignService;

        @Autowired
        private ThreadPoolExecutor executor;

        @Override
        public IPage<PmsSkuInfo> getPmsSkuInfoPage(QueryVo<PmsSkuInfo> queryVo) {

        Page<PmsSkuInfo> paramPage = new Page<>();

        paramPage.setCurrent(queryVo.getCurrentPage());

        paramPage.setSize(queryVo.getPageSize());

        QueryWrapper<PmsSkuInfo> wrapper = new QueryWrapper<>();

        PmsSkuInfo pmsSkuInfo = queryVo.getPayload();

        if(!ObjectUtils.isEmpty(pmsSkuInfo)){

            if(pmsSkuInfo.getCatalogId() != null){
                wrapper.eq("catalog_id", pmsSkuInfo.getCatalogId());
            }
            if(pmsSkuInfo.getBrandId() != null){
                wrapper.eq("brand_id", pmsSkuInfo.getBrandId());
            }
            if(pmsSkuInfo.getMaxPrice() != null){
                wrapper.le("price", pmsSkuInfo.getMaxPrice());
            }
            if(pmsSkuInfo.getMinPrice() != null && pmsSkuInfo.getMinPrice().compareTo(new BigDecimal("0"))==0){
                wrapper.ge("price", pmsSkuInfo.getMinPrice());
            }
        }
        if(!ObjectUtils.isEmpty(queryVo.getStartTime())){
            wrapper.gt("create_time", queryVo.getStartTime());
        }
        if(!ObjectUtils.isEmpty(queryVo.getEndTime())){
            wrapper.lt("create_time", queryVo.getEndTime());
        }
        wrapper.orderByDesc("create_time");

        Page<PmsSkuInfo> page = this.page(paramPage, wrapper);
            List<PmsSkuInfo> records = page.getRecords();
            if(!CollectionUtils.isEmpty(records)){

                List<Long> brandIds = records.stream().map(PmsSkuInfo::getBrandId).collect(Collectors.toList());
                List<Long> catalogIds = records.stream().map(PmsSkuInfo::getCatalogId).collect(Collectors.toList());
                List<PmsBrand> brands = brandService.list(new QueryWrapper<PmsBrand>().select("brand_id","name").in("brand_id", brandIds));

                Map<Long, String> brandMap = brands.stream().collect(Collectors.toMap(PmsBrand::getBrandId, PmsBrand::getName, (v, v1) -> v));
                List<PmsCategory> categories = categoryService.list(new QueryWrapper<PmsCategory>().select("cat_id","name").in("cat_id", catalogIds));

                Map<Long, String> categoryMap = categories.stream().collect(Collectors.toMap(PmsCategory::getCatId, PmsCategory::getName, (v, v1) -> v));

                records.forEach(s->{
                    s.setBrandName(brandMap.get(s.getBrandId()));
                    s.setCatalogName(categoryMap.get(s.getCatalogId()));
                });
            }
        return page;
        }

    @Override
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {

        SkuItemVo itemVo = new SkuItemVo();

        CompletableFuture<PmsSkuInfo> infoFuture = CompletableFuture.supplyAsync(() -> {
            // sku基本信息
            PmsSkuInfo skuInfo = this.getById(skuId);

            itemVo.setInfo(skuInfo);

            return skuInfo;
        }, executor);


        CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((skuInfo) -> {
            // 销售属性
            Long spuId = skuInfo.getSpuId();

            List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(spuId);

            itemVo.setSaleAttr(saleAttrVos);

        }, executor);

        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((skuInfo) -> {
            // 介绍信息
            Long spuId = skuInfo.getSpuId();

            PmsSpuInfoDesc infoDesc = spuInfoDescService.getById(spuId);

            itemVo.setDesc(infoDesc);

        }, executor);

        CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((skuInfo) -> {
            // 规格信息
            Long spuId = skuInfo.getSpuId();

            Long catalogId = skuInfo.getCatalogId();

            List<SpuItemAttrGroupVo> groupAttrs = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId, catalogId);

            itemVo.setGroupAttrs(groupAttrs);

        }, executor);

        CompletableFuture<Void> imgFuture = CompletableFuture.runAsync(() -> {
            List<PmsSkuImages> images = skuImagesService.getImagesBySkuId(skuId);

            itemVo.setImages(images);
        });

        //查看库存信息
        CompletableFuture<Void> stockFuture = CompletableFuture.runAsync(() -> {

            List<SkuHasStockTo> hasStockVos =  wareFeignService.getSkuHasStock(Collections.singletonList(skuId));
            if(!CollectionUtils.isEmpty(hasStockVos)){
                SkuHasStockTo hasStockTo = hasStockVos.get(0);
                itemVo.setHasStock(hasStockTo.getHasStock());
            }else{
                itemVo.setHasStock(false);
            }
        });
        //当前sku是否包含秒杀数据
        CompletableFuture<Void> skuSeckillFuture = CompletableFuture.runAsync(() -> {

            R<SeckillSkuTo> r = seckillFeignService.getSkuSeckillInfo(skuId);
            if(r!=null && r.getCode() == R.SUCCESS ){
                itemVo.setSeckillSkuTo(r.getData());
            }
        });

        CompletableFuture.allOf(saleAttrFuture, baseAttrFuture, descFuture, imgFuture,stockFuture, skuSeckillFuture).get();
        return itemVo;
    }

    @Override
    public List<CommonSelectVo> getSkuListByKeyWord(String keyword) {

        QueryWrapper<PmsSkuInfo> wrapper = new QueryWrapper<>();

        if(!ObjectUtils.isEmpty(keyword)){
            wrapper.like("sku_name", keyword);
        }
        List<PmsSkuInfo> list = this.list(wrapper);
        if(!CollectionUtils.isEmpty(list)){
            List<CommonSelectVo> voList = list.stream().map(e -> {

                return new CommonSelectVo(e.getSkuName(), String.valueOf(e.getSkuId()));
            }).collect(Collectors.toList());
            return voList;
        }
        return null;
    }

}
